package org.footballmanager.pandafootball.system.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.footballmanager.pandafootball.common.constants.Constants;
import org.footballmanager.pandafootball.common.util.DateUtils;
import org.footballmanager.pandafootball.common.util.StringUtil;
import org.footballmanager.pandafootball.system.domain.FootDj;
import org.footballmanager.pandafootball.system.domain.FootPerson;
import org.footballmanager.pandafootball.system.domain.FootReward;
import org.footballmanager.pandafootball.system.domain.FootRewardDetail;
import org.footballmanager.pandafootball.system.form.impl.FootRewardDetailSearchForm;
import org.footballmanager.pandafootball.system.mapper.FootRewardDetailMapper;
import org.footballmanager.pandafootball.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class FootRewardDetailServiceImpl extends ServiceImpl<FootRewardDetail> implements FootRewardDetailService {
    //抽取多少次后停止上涨每次抽取的金币数
    private static final Integer REWARDTOTALTIMES = 4;
    @Autowired
    private FootRewardDetailMapper footRewardDetailMapper;
    @Autowired
    private FootRewardService footRewardService;
    @Autowired
    private FootPersonService footPersonService;
    @Autowired
    private FootUserPersonService footUserPersonService;
    @Autowired
    private FootTaxService footTaxService;
    @Autowired
    private FootDjService footDjService;
    @Autowired
    private FootTeamService footTeamService;

    /**
     * 查询
     *
     * @param entityname          实体类名
     * @param map                 参数
     * @param footRewardDetailSearchForm 条件
     */
    @Override
    public void search(String entityname, Model map, FootRewardDetailSearchForm footRewardDetailSearchForm) {
        map.addAttribute(String.format(Constants.FORMNAME, entityname), footRewardDetailSearchForm);
        Page<FootRewardDetail> page = PageHelper.startPage(footRewardDetailSearchForm.getPageIndex(), footRewardDetailSearchForm.getPageSize());
        List<FootRewardDetail> list = this.findall(footRewardDetailSearchForm);
        map.addAttribute(Constants.PI, page.toPageInfo());
        map.addAttribute(String.format(Constants.LISTENTITY, entityname), list);
    }

    /**
     * 删除所有
     *
     * @param footRewardDetailSearchForm 条件
     * @param request             请求
     */
    @Override
    public void deleteAll(FootRewardDetailSearchForm footRewardDetailSearchForm, HttpServletRequest request) {
        if (footRewardDetailSearchForm.getSelectIds() != null) {
            String[] result = footRewardDetailSearchForm.getSelectIds().split(Constants.COMMA);
            for (String id : result) {
                this.delete(Long.parseLong(id), request);
            }
        }
    }

    /**
     * 翻页查询
     *
     * @param footRewardSearchForm
     * @return
     */
    @Override
    public List<FootRewardDetail> findall(FootRewardDetailSearchForm footRewardDetailSearchForm) {
        return footRewardDetailMapper.findall(footRewardDetailSearchForm);
    }

    /**
     * 根据主键查询记录
     * @param id 抽奖记录主键
     * @return 抽奖记录
     */
    @Override
    public FootRewardDetail get(Serializable id) {
        return footRewardDetailMapper.findById(id);
    }

    /**
     * 根据用户主键获取今日抽取记录列表
     *
     * @param userId 用户主键
     * @return 今日抽取记录列表
     */
    @Override
    public List<FootRewardDetail> findTodayDataByUserId(Long userId) {
        Example example = new Example(FootRewardDetail.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", userId);
        criteria.andGreaterThanOrEqualTo("rewardTime", DateUtils.getNowDate());
        criteria.andEqualTo("delFlag", 0);
        return this.findall(example);
    }

    /**
     * 免费抽奖
     *
     * @param userId 用户主键
     * @param request 请求
     */
    @Override
    @Transactional
    public FootPerson rewardFree(Long userId, HttpServletRequest request) {
        return updateDetailInfo(userId, 0, request);
    }

    /**
     * 收费抽奖
     *
     * @param userId 用户主键
     */
    @Override
    @Transactional
    public FootPerson reward(Long userId, HttpServletRequest request) {
        return updateDetailInfo(userId, 1, request);
    }

    private FootPerson updateDetailInfo(Long userId, int type, HttpServletRequest request){
        FootPerson p = null;
        FootRewardDetail detail = new FootRewardDetail();
        detail.setRewardTime(new Date());
        FootReward reward = footRewardService.findByUserId(userId);
        reward.setMustGet(reward.getMustGet() + 1);
        p = this.processQy(detail, reward, userId, request);
        //team减去花费 znx等更新
        if(type != 0){
            footTeamService.payQy(userId, reward.getNeedPay(), StringUtil.getFullNameFromPerson(p), request);
            detail.setPay(reward.getNeedPay());
        }else{
            detail.setPay(0D);
        }
        detail.setType(type);
        detail.setUserId(userId);
        //随机获取球员概率及球员
        this.save(detail, request);
        //更新抽奖机率
        this.updateOdds(reward, userId, request);
        //更新抽奖次数及总次数
        footRewardService.updateTimesByType(userId, type, request);
        return p;
    }

    private FootPerson processQy(FootRewardDetail detail, FootReward reward, Long userId, HttpServletRequest request) {
        FootPerson p;
        if(reward.getMustGet() % footTaxService.getResetReward() == 0){
            reward.setMustGet(0);
            p = footPersonService.getDjQy(userId, footTaxService.getDjId(), request);
            detail.setQyId(p.getId());
            detail.setDjId(p.getDjId());
        }else{
            //根据机率随机获取球员
            p = footPersonService.findQyByOdds(userId, reward, request);
            detail.setQyId(p.getId());
            detail.setDjId(p.getDjId());
        }
        return p;
    }

    private void updateOdds(FootReward reward, Long userId, HttpServletRequest request) {
        //机率变更放到reward里
        if(reward.getTotalTimes() > reward.getShowOdds()){
            Integer oldMod = reward.getRewardModTimes();
            Integer mod = reward.getTotalTimes() / reward.getShowOdds();
            if(oldMod != mod){
                //处理几率问题
                processOdds(mod, reward, request);
            }
        }
    }

    private void processOdds(Integer mod, FootReward reward, HttpServletRequest request) {
        if(reward.getTotalTimes() < footTaxService.getStopIncrease()){
            reward.setNeedPay(reward.getNeedPay() + footTaxService.getRewardPay());
        }
        reward.setRewardModTimes(mod);
        if(reward.getOdds() < reward.getShowOdds()){
            reward.setOdds(reward.getOdds() + footTaxService.getOdds());
        }
        //处理等级倍率问题
        processLevel(reward, request);
    }

    private void processLevel(FootReward reward, HttpServletRequest request) {
        List<FootDj> djList = footDjService.getall();
        for(FootDj dj: djList){
            if(dj.getQydj().equals("大众/白人")){
                reward.setWhite(reward.getWhite() - reward.getOdds() < dj.getMaxRatio() ? dj.getMaxRatio() : reward.getWhite() - reward.getOdds());
            }else if(dj.getQydj().equals("普通球星")){
                reward.setGreen(reward.getGreen() - reward.getOdds() < dj.getMaxRatio() ? dj.getMaxRatio() : reward.getGreen() - reward.getOdds());
            }else if(dj.getQydj().equals("洲际球星")){
                reward.setBlue(reward.getBlue() + reward.getOdds() >= dj.getMaxRatio() ? dj.getMaxRatio() : reward.getBlue() + reward.getOdds());
            }else if(dj.getQydj().equals("超际球星")){
                reward.setPurple(reward.getPurple() + reward.getOdds() >= dj.getMaxRatio() ? dj.getMaxRatio() : reward.getPurple() + reward.getOdds());
            }else{
                reward.setOrange(reward.getOrange() + reward.getOdds() >= dj.getMaxRatio() ? dj.getMaxRatio() : reward.getOrange() + reward.getOdds());
            }
        }
    }

}
